<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>JS 闭包3</title>
</head>

<body>

</body>




<script>

    // 闭包的最大用处有两个:
    // 1. 一个是前面提到的可以读取函数内部的变量;
    // 2. 一个就是让这些变量的值始终保持在内存中,不会被回收机制所回收；


    // function f1() {
    //     　　　　var n = 99;
    //     　　　　nAdd = function () {
    //                 n += 1
    //     }
    //     　　　　function f2() {
    //         　　　　　　alert(n);
    //     　　　　}
    //     　　　　return f2;
    // 　　}
    // 　　var result = f1();
    // 　　result();
    // 　　nAdd();
    // 　　result();








    // 使用闭包的注意点：
    // 1.由于闭包会使得函数中的变量都被保存在内存中，内存消耗很大，所以不能滥用闭包，否则会造成网页的性能问题，在IE中可能导致内存泄露。解决方法是，在退出函数之前，将不使用的局部变量全部删除。
    // 2.闭包会在父函数外部，改变父函数内部变量的值。所以，如果你把父函数当作对象使用，把闭包当作它的公用方法，把内部变量当作它的私有属性，这时一定要小心，不要随便改变父函数内部变量的值。


    // var name = "The Window";
    // var object = {
    //     name: "My Object",
    //     getNameFunc: function () {
    //         return function () {
    //             ;
    //             return this.name;
    //         };
    //     }
    // };
    // alert(object.getNameFunc()());




    // function outerFun() {
    //     var a = 0;
    //     alert(a);
    // }
    // var a = 4;
    // outerFun();
    // alert(a);



    // 在函数内部使用了var关键字 维护a的作用域在outFun()内部.



    // function outerFun() {
    //     a = 0;
    //     alert(a);
    // }
    // var a = 4;
    // outerFun();
    // alert(a);



    // 作用域链是描述一种路径的术语,沿着该路径可以确定变量的值 .当执行a=0时,因为没有使用var关键字,因此赋值操作会沿着作用域链到var a=4;  并改变其值.

    

    



// 函数的作用域是在定义函数时候就已经确定，而不是在执行的时候确定



    // function f(x) {
    //     var g = function () {
    //         return x;
    //     }
    //     return g;
    // }
    // var h = f(1);
    // alert(h());




    // 假设函数h的作用域是在执行alert(h())确定的，那么此时h的作用域链是：h的活动对象->alert的活动对象->window对象。

    // 假设函数h的作用域是在定义时确定的，就是说h指向的那个匿名函数在定义的时候就已经确定了作用域。那么在执行的时候，h的作用域链为：h的活动对象->f的活动对象->window对象


    // 如果第一种假设成立，那输出值就是undefined

    // 如果第二种假设成立，输出值则为1



    // 说明函数的作用域确实是在定义这个函数的时候就已经确定了。





</script>

</html>